// PGraphic Classes.
//==================

// The PGraphic Class.
// This class contains, updates and draws the PGraphic canvas assigned to it.
class pp_pGraphics {
  int x, y, depth, index;
  PGraphics graphic;
  
  pp_pGraphics (int PosX, int PosY, int objWidth, int objHeight, int Depth) {
    x = PosX;
    y = PosY;
    depth = Depth;
    graphic = createGraphics(objWidth, objHeight);
    
    // Set default transparent bg.
    graphic.beginDraw();
    graphic.background(0,0);
    graphic.endDraw();
  }
  
  void draw() {
    pp_drawPGraphic (x, y, depth, index);
  }
}

// PGraphic Functions.
// ===================

int pp_createGraphics (int PosX, int PosY, int objWidth, int objHeight, int Depth) {
  pp_graphics.add(new pp_pGraphics (PosX, PosY, objWidth, objHeight, Depth));
  pp_graphics.get(pp_graphics.size() - 1).index = pp_graphics.size() - 1;
  return pp_graphics.size() - 1;
}

void pp_updatePGraphics () {
  for (pp_pGraphics graphic : pp_graphics) {
    graphic.draw();
  }
}

void pp_drawPGraphicToMatrix (int x, int y, int testResult, int graphicIndex) {  
  
  // Grab graphic from Arraylist.
  PGraphics graphic = pp_graphics.get(graphicIndex).graphic;
  
  // Fail safe in case graphic is missing.
  if (graphic == null) {testResult = 0;}
  
  switch (testResult) {    
    // If partially on screen...
    case 1:    
      // Get margins.
      int startX = (x < pp_displayX) ? (pp_displayX - x) : 0;
      int endX = (x + graphic.width >= int(width/pp_pixelSize) + pp_displayX) ? ((int(width/pp_pixelSize) + pp_displayX) - x) : graphic.width;
      int startY = (y < pp_displayY) ? (pp_displayY - y) : 0;
      int endY = (y + graphic.height >= int(height/pp_pixelSize) + pp_displayY) ? ((int(height/pp_pixelSize) + pp_displayY) - y) : graphic.height;
      
      // Render partially to screen.
      for (int i = startX; i < endX; i++) {
        for (int k = startY; k < endY; k++) {
          pp_drawPixel(i + x, k + y, graphic.pixels[i + (k * graphic.width)]);
        }
      }
      break;
    
    // If entirely on screen, render all.
    case 2:
      for (int i = 0; i < graphic.width; i++) {
        for (int k = 0; k < graphic.height; k++) {
          pp_drawPixel(i + x, k + y, graphic.pixels[i + (k * graphic.width)]);
        }
      }
      break;
  }
}

void pp_drawPGraphic (int x, int y, int depth, int graphicIndex) {
  
  // Grab graphics from Arraylist.
  PGraphics graphic = pp_graphics.get(graphicIndex).graphic;
  
  // Test if all edges are on screen.
  int testResult = pp_toInt(pp_testOnScreen(x, y)) + pp_toInt(pp_testOnScreen(x + graphic.width, y + graphic.height));
  
  // If partially or completely on-screen, render it.
  if (testResult > 0) {
    if (depth == 0) {
      pp_drawPGraphicToMatrix (x, y, testResult, graphicIndex);
    
    // Else, add to depthBuffer.
    } else {
      depthBuffer.append(nf(depth,4) + "2" + str(pp_signToInt(x)) + nf(abs(x),4) + str(pp_signToInt(y)) + nf(abs(y),4) + str(testResult) + nf(graphicIndex,4));
    }
  }
}
